﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using MS.InformationManagement.Support;
using Microsoft.SharePoint;
using MS.InformationManagement.Support.Constants;
using MS.InformationManagement.DAL.DocumentCenter;
using MS.InformationManagement.Core.Support;
using Microsoft.SharePoint.Linq;

namespace MS.InformationManagement.BLL.AllowingAccessControl
{
    public class AllowingAccessControl
    {

        public static bool AccesToPage(string CurrentUrl)
        {
            bool result = false;

            if (!SPContext.Current.Web.CurrentUser.IsSiteAdmin)
                result = HaveAccesRibbonActions(CurrentUrl);
            else
                result = true;


            return result;
        }

        private static bool HaveAccesRibbonActions(string CurrentUrl)
        {
            string currentLibrary = SPContext.Current.List != null ? SPContext.Current.List.Title : string.Empty;
            
            if (AllowedPublicPages.IsPagePublicPage(CurrentUrl))
                return true;

            if (!string.IsNullOrEmpty(currentLibrary) && currentLibrary.Equals(SPContext.Current.Web.CurrentUser.LoginName.GetUserWithOutDomain()))
                return true;

            string perfil = PeopleHelper.GetPropertyUserProfile(GlobalConstants.UP_USER_PERFIL, SPContext.Current.Web.CurrentUser.LoginName);

            if (string.IsNullOrEmpty(perfil))
                return false;//throw new Exception("El usuario " + SPContext.Current.Web.CurrentUser.LoginName + " no ha sido configurado");
            else
                return HasPerfilPermissions(perfil, CurrentUrl, currentLibrary);
            
        }

        public static List<Roles> GetRibbonAllowedActionsCurrentUser()
        {
            List<Roles> result = new List<Roles>();

            if (SPContext.Current.Web.CurrentUser.IsSiteAdmin)
                result = getAllRoles();
            else
            {
                string currentPerfil = PeopleHelper.GetPropertyUserProfile(GlobalConstants.UP_USER_PERFIL, SPContext.Current.Web.CurrentUser.LoginName);
                if (string.IsNullOrEmpty(currentPerfil))
                    result = null;//throw new Exception("El usuario " + SPContext.Current.Web.CurrentUser.LoginName + " no ha sido configurado");
                else
                {
                    SPSecurity.RunWithElevatedPrivileges(delegate()
                    {
                        using (var currentSite = new SPSite(SPContext.Current.Site.ID))
                        {
                            using (var currentWeb = currentSite.OpenWeb())
                            {
                                VincularPerfiles perfil = GetPerfil(currentPerfil, currentWeb);
                                var allRoles = GetAllRoles(currentPerfil, currentWeb);
                                var res = (from rolRibbon in allRoles
                                           where rolRibbon.AccionRibbon != null
                                           && rolRibbon.AccionRibbon.Value == true &&
                                           (from role in perfil.TipoRole.ToList()
                                            select role.Id).Contains(rolRibbon.Id)
                                           select rolRibbon).ToList();
                                result.AddRange(res.ToList());
                            }
                        }
                    });
                }
                
            }

            if (SPContext.Current.Web.CurrentUser.IsSiteAdmin)
            {
                Roles rol = new Roles();
                rol.Role = GlobalConstants.ROLE_ADMINISTRATION;

                result.Add(rol);
            }
            return result;

        }

        private static List<Roles> getAllRoles()
        {
            
            using (var dc = new DCDocumentCenterDataContext(SPContext.Current.Web.Url))
            {
                Dictionary<string, string> dic = new Dictionary<string,string>();
                 var a = (from rol in dc.Roles
                        select rol).ToList();
                 return a;
            }
        }

        public static Boolean HasPerfilPermissions(string Perfil, string Url, string ListName)
        {
            bool result = false;

            SPSecurity.RunWithElevatedPrivileges(delegate()
            {
                using (var currentSite = new SPSite(SPContext.Current.Site.ID))
                {
                    using (var currentWeb = currentSite.OpenWeb())
                    {
                        var currentPerfil = GetPerfil(Perfil, currentWeb);
                        result = currentPerfil.TipoRole.OfType<Roles>().Where(c => c.PáginaRole.ToUpper() == Url.ToUpper() || c.PáginaRole.ToUpper() == ListName.ToUpper()).Count() > 0;
                    } 
                }
            });

            return result;                     
        }
        
        public static Boolean HasPerfilPermissions(string Perfil, string Url)
        {
            bool result = false;

            SPSecurity.RunWithElevatedPrivileges(delegate()
            {
                using (var currentSite = new SPSite(SPContext.Current.Site.ID))
                {
                    using (var currentWeb = currentSite.OpenWeb())
                    {
                        var currentPerfil = GetPerfil(Perfil, currentWeb);
                        result = currentPerfil.TipoRole.OfType<Roles>().Where(c => c.PáginaRole.ToUpper() == Url.ToUpper()).Count() > 0;
                    }
                }
            });

            return result;
        }

        public static IEnumerable<Roles> GetAllRoles(string perfil, SPWeb currentWeb)
        {
            SPListItemCollection roles = currentWeb.Lists[GlobalConstants.LIST_ROLES].GetItems();
            var rolesResult = from rol in roles.OfType<SPListItem>()
                              select new Roles()
                              {
                                  AccionRibbon = rol[CustomSiteColumns.FIELD_INTERNAL_ROL_RIBBON_ACTION] == null ? false : Boolean.Parse(rol[CustomSiteColumns.FIELD_INTERNAL_ROL_RIBBON_ACTION].ToString()),
                                  Id = int.Parse(rol[SPBuiltInFieldId.ID].ToString()),
                                  Role = rol[CustomSiteColumns.FIELD_INTERNAL_NAME_ROLE_SHOW].ToString(),
                                  AccionTab = rol[CustomSiteColumns.FIELD_INTERNAL_ROL_TAB_ACTION] == null ? new AccionTab() : (AccionTab)Enum.Parse(typeof(AccionTab), rol[CustomSiteColumns.FIELD_INTERNAL_ROL_TAB_ACTION].ToString().Replace(" ", string.Empty))

                              };
            return rolesResult;
        }

        public static VincularPerfiles GetPerfil(string perfil, SPWeb currentWeb)
        {
            string camlQuery = string.Format("<Where><Eq><FieldRef Name='Perfil_User' /><Value Type='Text'>{0}</Value></Eq></Where>", perfil);
            SPQuery query = new SPQuery() { Query = camlQuery };
            SPListItem currentUserPerfil = currentWeb.Lists[GlobalConstants.LIST_PERFILES_ROL].GetItems(query).OfType<SPListItem>().FirstOrDefault();
            return new VincularPerfiles()
            {
                TipoRole = getProfileRoles(currentUserPerfil,currentWeb),
                Perfil = currentUserPerfil[CustomSiteColumns.FIELD_INTERNAL_PERFIL].ToString()
            };
        }

        private static EntitySet<Roles> getProfileRoles(SPListItem roles, SPWeb currentWeb)
        {
            SPFieldLookupValueCollection rolesCollection = new SPFieldLookupValueCollection(roles[CustomSiteColumns.FIELD_INTERNAL_ROLES_PERFIL] +"");
            EntitySet<Roles> rolesResult = new EntitySet<Roles>();
            foreach (var lookupValue in rolesCollection)
                rolesResult.Add(new Roles(){ Id = lookupValue.LookupId, PáginaRole = getRolePage(lookupValue.LookupId, currentWeb) });
            return rolesResult;
        }

        private static string getRolePage(int roleId, SPWeb currentWeb)
        { 
            string camlQuery = string.Format("<Where><Eq><FieldRef Name='ID' /><Value Type='Counter'>{0}</Value></Eq></Where>",roleId);
            string viewFields = string.Format("<FieldRef Name='{0}'/>",CustomSiteColumns.FIELD_INTERNAL_PAGE_ROL);
            SPQuery query = new SPQuery() { Query = camlQuery, ViewFields = viewFields };
            return currentWeb.Lists[GlobalConstants.LIST_ROLES].GetItems(query)[0][CustomSiteColumns.FIELD_INTERNAL_PAGE_ROL].ToString();
        }

        private static Roles getRol(SPListItem item)
        {
            SPFieldLookupValue rol = new SPFieldLookupValue(item[CustomSiteColumns.FIELD_DISPLAY_ROLE_LOOKUP].ToString());
            return new Roles() { Id = rol.LookupId, Role = rol.LookupValue };
        }

    }
}
